<template>
  <div class="Cutting">
    <div class="modalMain">
      <div class="modalFormBox">
        <div class="modalFormItem">
          <span class="label" title="剖切方向">剖切方向</span>
          <span class="content">
            <a-select v-model="direction" style="width: 100%" @change="onClear">
              <a-select-option value="从上往下">从上往下</a-select-option>
              <a-select-option value="从下往上">从下往上</a-select-option>
              <a-select-option value="从左往右">从左往右</a-select-option>
              <a-select-option value="从右往左">从右往左</a-select-option>
              <a-select-option value="从前往后">从前往后</a-select-option>
              <a-select-option value="从后往前">从后往前</a-select-option>
            </a-select>
          </span>
        </div>

        <div class="modalFormItem">
          <span class="label" title="剖切墙移动">剖切墙移动</span>
          <span class="content">
            <div class="flexContent">
              <a-slider v-model="distance" :max="disMax" :min="disMin" style="flex: 5" @change="changedistance" />
              <a-input-number v-model="distance" style="flex: 3" :min="disMin" :max="disMax" size="small" />
            </div>
          </span>
        </div>

        <div class="modalFormItem">
          <span class="label" title="剖切墙颜色">剖切墙颜色</span>
          <span class="content">
            <a-input v-model="wallColor" type="color" class="planecolorPicker" />
          </span>
        </div>

        <div class="modalFormItem">
          <span class="label" title="透明度">透明度</span>
          <span class="content">
            <a-input-number v-model="transparency" size="default" :min="0.1" :max="1" :step="0.1" style="width: 100%" />
          </span>
        </div>

        <!--        <div class="modalFormItem">-->
        <!--          <span class="label" title="剖切面高亮">剖切面高亮</span>-->
        <!--          <span class="content">-->
        <!--            <a-switch v-model="showEdge" checked-children="是" un-checked-children="否"> </a-switch>-->
        <!--          </span>-->
        <!--        </div>-->

        <!--        <div class="modalFormItem">-->
        <!--          <span class="label" title="高亮线颜色">高亮线颜色</span>-->
        <!--          <span class="content">-->
        <!--            <div class="flexContent">-->
        <!--              <a-slider-->
        <!--                v-model="edgeWidth"-->
        <!--                :min="0"-->
        <!--                :max="20"-->
        <!--                :step="0.1"-->
        <!--                :disabled="!showEdge"-->
        <!--                style="flex: 5"-->
        <!--              ></a-slider>-->
        <!--              <a-input-number style="flex: 3" v-model="edgeWidth" :min="0" :max="20" size="small" />-->
        <!--            </div>-->
        <!--          </span>-->
        <!--        </div>-->

        <div class="modalFormItem">
          <span class="label" title="动画时间(秒)">动画时间(秒)</span>
          <span class="content">
            <a-input-number v-model="animationTime" size="default" :min="1" :max="100" style="width: 100%" />
          </span>
        </div>
      </div>
    </div>
    <div class="modalFooter">
      <div class="modalBtnGroup">
        <a-button type="primary" size="default" :disabled="loading" ghost @click="start">
          <span v-if="loading">正在分析</span>
          <span v-else>开始分析</span>
        </a-button>
        <a-button type="primary" size="default" style="margin-left: 10px" :disabled="!loading" ghost @click="dynamic">
          动态效果
        </a-button>
        <a-button type="primary" size="default" style="margin-left: 10px" ghost @click="onClear"> 结束 </a-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dynaCut: null,
      distance: 0,
      disMax: 100,
      disMin: 0,
      models: [],
      direction: '从左往右',
      wallColor: '#99FDFF',
      showEdge: true,
      edgeWidth: 1.0,
      edgeColor: '#FF1100',
      loading: false,
      eventHandler: null,
      animationTime: 5,
      animationState: null,
      transparency: 0.3,
      extent: {},
      minX: 0,
      maxX: 0,
      minY: 0,
      maxY: 0,
      minZ: 0,
      maxZ: 0,
      // 是否已选择模型
      chooseModel: false,
      // 是否是单个模型
      singleModel: true,
    }
  },
  computed: {},
  mounted() {
    console.log('Cutting')
  },
  beforeDestroy() {
    this.onClear()
  },
  methods: {
    changedistance(val) {
      this.distance = val
      if (window.dynamicSectionAnalysis) {
        // 设置剖切面距离
        window.dynamicSectionAnalysis.distance = val
      }
    },
    start() {
      // 开始分析
      // 旧方法
      // this.cutting()
      // 新方法
      this.startClipping()
    },
    onClear() {
      // 移除分析显示结果
      var _that = this
      // 旧方法
      // if (_that.dynaCut) {
      //   // 清除开始按钮加载状态
      //   _that.loading = false
      //   _that.webGlobe.entities.removeAll()
      //   _that.dynaCut = _that.createDynamicCutting(_that.models, [], {})
      // }
      // 新方法
      // 移除分析显示结果
      if (window.dynamicSectionAnalysis) {
        window.component.viewer.entities.removeAll()
        window.dynamicSectionAnalysis.removeAll()
        window.dynamicSectionAnalysis = null
      }
      // 清除开始按钮加载状态
      _that.loading = false
      // 清除动画效果
      clearInterval(_that.animationState)
      _that.animationState = null
    },
    // 分析方法--旧
    cutting() {
      const _that = this
      const layer = window.component.viewer.scene._layers

      _that.models = []
      // 现在是存在_m3dLayersMap，之前为_sceneLayerMap，暂不删除，都保留
      const m3dLayer = layer._m3dLayersMap
      if (m3dLayer !== undefined && m3dLayer._length > 0) {
        const mapObj = m3dLayer._obj
        for (var index in mapObj) {
          const m3dLayerMap = mapObj[index]
          if (m3dLayerMap !== undefined) {
            _that.models.push(m3dLayerMap)
          }
        }
      } else {
        const map = layer._sceneLayerMap
        const mapObj = map._obj
        for (const index in mapObj) {
          const obj = mapObj[index]
          if (obj !== undefined) {
            const layerobj = obj._m3dLayerMap._obj
            for (var item in layerobj) {
              const m3dLayerMap = layerobj[item]
              if (m3dLayerMap !== undefined) {
                _that.models.push(m3dLayerMap)
              }
            }
          }
        }
      }

      if (_that.models.length === 0) {
        _that.$message.warning('未找到选待分析模型，确认是否勾选！')
      }
      var direcArr = []
      const model = _that.models[0]
      // 获取当前三维范围
      // debugger
      _that.distance = model.boundingSphere.radius
      const disMax = _that.distance
      // const disMin = -_that.distance
      var maxHeight = Math.abs(model.root.boundingVolume.maximumHeight)
      var minHeight = Math.abs(model.root.boundingVolume.minimumHeight)
      switch (_that.direction) {
        case '从上往下':
          direcArr = [0, 0, -1]
          _that.distance = -maxHeight
          _that.disMax = minHeight
          _that.disMin = -maxHeight
          break
        case '从下往上':
          direcArr = [0, 0, 1]
          _that.distance = -minHeight
          _that.disMax = maxHeight
          _that.disMin = -minHeight
          break
        case '从左往右':
          direcArr = [1, 0, 0]
          _that.disMax = disMax * 2
          _that.disMin = 0
          _that.distance = _that.disMin
          break
        case '从右往左':
          direcArr = [-1, 0, 0]
          _that.disMax = 0
          _that.disMin = -disMax * 2
          _that.distance = _that.disMin
          break
        case '从前往后':
          direcArr = [0, 1, 0]
          _that.disMax = disMax * 2
          _that.disMin = 0
          _that.distance = 0
          break
        case '从后往前':
          direcArr = [0, -1, 0]
          _that.disMax = 0
          _that.disMin = -disMax * 2
          _that.distance = _that.disMin
          break
        default:
          direcArr = [1, 0, 0]
          break
      }
      const rgbColor = _that.convertHexToRGB(_that.wallColor)
      const wallColor = rgbColor.split(', ')
      var plane = new Cesium.ClippingPlane(new Cesium.Cartesian3(...direcArr), 0.0)
      _that.dynaCut = _that.createDynamicCutting(_that.models, [plane], {
        color: new Cesium.Color(wallColor[0] / 255, wallColor[1] / 255, wallColor[2] / 255, _that.transparency),
      })
      // 设置切面回调函数
      _that.dynaCut.planes[0].plane.plane = new Cesium.CallbackProperty(function (date) {
        console.log(date)
        // 按钮改为加载状态，避免多次点击
        _that.loading = true
        // 设置剖切面距离
        plane.distance = -_that.distance
        _that.dynaCut.tilesets[0].clippingPlanes.edgeWidth = _that.showEdge ? _that.edgeWidth : 0
        const edgeRbgColor = _that.convertHexToRGB(_that.edgeColor)
        const edgeColor = edgeRbgColor.split(', ')
        _that.dynaCut.tilesets[0].clippingPlanes.edgeColor = new Cesium.Color(
          edgeColor[0] / 255,
          edgeColor[1] / 255,
          edgeColor[2] / 255,
          1,
        )
        return Cesium.Plane.transform(
          plane,
          _that.models[0].modelMatrix,
          new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_X, 0.0),
        )
      }, false)
    },
    convertHexToRGB(color) {
      // 颜色转换
      if (color.length === 4) {
        let extendedColor = '#'
        for (let i = 1; i < color.length; i++) {
          extendedColor += color.charAt(i) + color.charAt(i)
        }
        color = extendedColor
      }
      const values = {
        r: parseInt(color.substr(1, 2), 16),
        g: parseInt(color.substr(3, 2), 16),
        b: parseInt(color.substr(5, 2), 16),
      }
      return `${values.r}, ${values.g}, ${values.b}`
    },
    dynamic() {
      // 动态效果
      // 旧方法
      // const self = this
      // if (self.animationState) {
      //   clearInterval(self.animationState)
      //   self.animationState = null
      // }
      // self.animationState = window.setInterval(() => {
      //   const step = (self.disMax - self.disMin) / (self.animationTime * 10)
      //   self.distance += step
      //   if (self.distance >= self.disMax) {
      //     clearInterval(self.animationState)
      //     self.animationState = null
      //     return
      //   }
      // }, 100)
      // 新方法
      const self = this
      if (self.animationState) {
        clearInterval(self.animationState)
        self.animationState = null
      }
      self.animationState = window.setInterval(() => {
        const step = (self.disMax - self.disMin) / (self.animationTime * 10)
        self.distance -= step
        if (window.dynamicSectionAnalysis) {
          // 设置剖切面距离
          window.dynamicSectionAnalysis.distance = self.distance
        }
        if (self.distance <= self.disMin) {
          clearInterval(self.animationState)
          self.animationState = null
          return
        }
      }, 100)
    },
    /**
     * 动态剖切
     * @function module:客户端可视化分析.AnalysisManager.prototype.createDynamicCutting
     * @param {Object} tileset 图层集
     * @param {Array} planes 平面集
     * @param {Object} options 动态剖切参数
     * @param {Color} [options.color=Color.WHITE.withAlpha(0.5)] 材质
     * @param {Number} [options.scaleHeight=2.5] 高度缩放比
     * @param {Number} [options.scaleWidth=2.5] 宽度缩放比
     *
     * @returns {Object} 返回对象
     */
    createDynamicCutting(tilesets, planes, options) {
      if (!Cesium.defined(tilesets) && tilesets.length > 0) {
        return undefined
      }
      var scaleHeight = Cesium.defaultValue(options.scaleHeight, 3.0)
      var scaleWidth = Cesium.defaultValue(options.scaleWidth, 3.0)
      let material = Cesium.Color.WHITE.withAlpha(0.5)
      let interaction = false
      const optionsParam = Cesium.defaultValue(options, {})
      material = Cesium.defaultValue(optionsParam.color, material)
      interaction = Cesium.defaultValue(optionsParam.interaction, false)
      console.log(interaction)
      const _that = this
      const cutPlanes = []
      const edgeRbgColor = _that.convertHexToRGB(_that.edgeColor)
      const edgeColor = edgeRbgColor.split(', ')
      for (var index in tilesets) {
        const tileset = tilesets[index]
        // const normal = planeitem._normal._cartesian3;
        tileset.clippingPlanes = new Cesium.ClippingPlaneCollection({
          planes,
          edgeColor: new Cesium.Color(edgeColor[0] / 255, edgeColor[1] / 255, edgeColor[2] / 255, 1),
          edgeWidth: _that.showEdge ? _that.edgeWidth : 0,
          unionClippingRegions: false,
        })
        const { radius } = tileset.boundingSphere
        const { transform } = tileset._root
        const center = new Cesium.Cartesian3()
        // 矩阵获取中心
        Cesium.Matrix4.getTranslation(transform, center)
        for (let i = 0; i < planes.length; i += 1) {
          const planeEntity = window.component.viewer.entities.add({
            // 计算平面(此平面由一个点，与法线构成)外一点到此平面上的投影点
            position: center,
            plane: {
              dimensions: new Cesium.Cartesian2(radius * scaleWidth, radius * scaleHeight),
              material,
            },
          })
          cutPlanes.push(planeEntity)
        }
      }
      return {
        tilesets,
        planes: cutPlanes,
      }
    },
    /**
     * 开始分析
     */
    startClipping() {
      const _that = this
      if (!_that.chooseModel) {
        _that.models = []
        const layer = window.component.viewer.scene._layers
        // 现在是存在_m3dLayersMap，之前为_sceneLayerMap，暂不删除，都保留
        const m3dLayer = layer._m3dLayersMap
        console.log('m3dLayer', layer)
        if (m3dLayer !== undefined && m3dLayer._length > 0) {
          const mapObj = m3dLayer._obj
          for (var index in mapObj) {
            const m3dLayerMap = mapObj[index]
            if (m3dLayerMap !== undefined) {
              const boundingSphere = m3dLayerMap.boundingSphere
              _that.compareMaxandMin(index, boundingSphere)
              _that.models.push(m3dLayerMap)
            }
          }
        } else {
          const map = layer._sceneLayerMap
          const mapObj = map._obj
          for (const index in mapObj) {
            const obj = mapObj[index]
            if (obj !== undefined) {
              const layerobj = obj._m3dLayerMap._obj
              for (var item in layerobj) {
                const m3dLayerMap = layerobj[item]
                if (m3dLayerMap !== undefined) {
                  // m3dLayerMap.debugShowBoundingVolume = true;
                  const boundingSphere = m3dLayerMap.boundingSphere
                  _that.compareMaxandMin(item, boundingSphere)
                  _that.models.push(m3dLayerMap)
                }
              }
            }
          }
        }
      }
      if (_that.models.length === 0) {
        _that.$message.warning('未找到选待分析模型，确认是否勾选！')
      }
      _that.chooseModel = true
      const viewer = window.component.viewer
      window.dynamicSectionAnalysis = window.dynamicSectionAnalysis || new Cesium.CuttingTool(viewer, _that.models)

      // 剖切方向
      const direction = this.clippingDirection()
      const rgbColor = _that.convertHexToRGB(_that.wallColor)
      const wallColor = rgbColor.split(', ')
      const color = new Cesium.Color(wallColor[0] / 255, wallColor[1] / 255, wallColor[2] / 255, _that.transparency)
      // 创建剖切对象实例
      window.dynamicSectionAnalysis.createModelCuttingPlane(new Cesium.Cartesian3(...direction), {
        distance: this.distance,
        color: color,
        // 剖切辅助面的宽高缩放比(基于模型球的半径)
        scaleHeight: 1.5,
        scaleWidth: 1.5,
      })
      _that.loading = true
    },
    /**
     * 获取模型范围最大最小值
     * */
    compareMaxandMin(item, boundingSphere) {
      console.log('compareMaxandMin', item, boundingSphere)
      const _that = this
      // 模型中心点
      const center = boundingSphere.center
      // 模型范围
      const radius = boundingSphere.radius ? boundingSphere.radius / 2 : 0
      const x = Math.abs(center.x) / 22000
      const y = Math.abs(center.y) / 22000
      const z = Math.abs(center.z) / 22000
      if (item === 1) {
        _that.maxX = x + radius
        _that.minX = x
        _that.maxY = y + radius
        _that.minY = y
        _that.maxZ = z + radius
        _that.minZ = z
      } else {
        _that.singleModel = false
        if (x + radius > _that.maxX) {
          _that.maxX = x + radius
        }
        if (x < _that.minX) {
          _that.minX = x
        }
        if (y + radius > _that.maxY) {
          _that.maxY = y + radius
        }
        if (y < _that.minY) {
          _that.minY = y
        }
        if (z + radius > _that.maxZ) {
          _that.maxZ = z + radius
        }
        if (z < _that.minZ) {
          _that.minZ = z
        }
      }
    },
    /**
     * 获取墙方向距离
     * */
    clippingDirection() {
      const _that = this
      var direcArr = []
      let disX = 100
      let disY = 100
      let disZ = 100
      let maxHeight = 100
      let minHeight = 0
      // 获取当前三维范围
      if (_that.singleModel) {
        const model = _that.models[0]
        const radius = model.boundingSphere.radius
        disX = radius
        disY = radius
        maxHeight = model.root.boundingVolume.maximumHeight
        minHeight = model.root.boundingVolume.minimumHeight
        disZ = (maxHeight - minHeight) / 2
      } else {
        // 多个模型时，无法仅根据其中一个确定剖切范围
        disX = Math.abs(_that.maxX - _that.minX)
        disY = Math.abs(_that.maxY - _that.minY)
        disZ = Math.abs(_that.maxZ - _that.minZ)
      }
      _that.distance = 0
      switch (_that.direction) {
        case '从上往下':
          direcArr = [0, 0, -1]
          _that.disMax = disZ
          _that.disMin = -disZ
          _that.distance = _that.disMax
          break
        case '从下往上':
          direcArr = [0, 0, 1]
          _that.disMax = disZ
          _that.disMin = -disZ
          _that.distance = _that.disMax
          break
        case '从左往右':
          direcArr = [1, 0, 0]
          _that.disMax = disX
          _that.disMin = -disX
          _that.distance = _that.disMax
          break
        case '从右往左':
          direcArr = [-1, 0, 0]
          _that.disMax = disX
          _that.disMin = -disX
          _that.distance = _that.disMax
          break
        case '从前往后':
          direcArr = [0, 1, 0]
          _that.disMax = disY
          _that.disMin = -disY
          _that.distance = _that.disMax
          break
        case '从后往前':
          direcArr = [0, -1, 0]
          _that.disMax = disY
          _that.disMin = -disY
          _that.distance = _that.disMax
          break
        default:
          direcArr = [1, 0, 0]
          break
      }
      return direcArr
    },
  },
}
</script>

<style lang="scss">
.Cutting {
  width: 400px;
  ::v-deep .el-color-picker {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  ::v-deep .el-color-picker__trigger {
    width: 100%;
  }
  .flexContent {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .modalFormItem {
    padding: 10px;
    display: flex;
    .label {
      width: 100px;
      text-align: left;
    }
    .content {
      flex: 1;
    }
  }
  .modalFooter {
    padding: 20px;
    text-align: center;
    .ant-btn {
      color: #fff;
    }
  }
  .ant-btn-background-ghost.ant-btn-primary[disabled] {
    color: #e8e8e8 !important;
  }
}
.cutting_menus {
  height: 40px;
  padding: 0 10px;
  margin-bottom: 5px;
  display: flex;
  align-items: center;

  .cutting_label {
    flex: 10;
  }

  .cutting_content {
    flex: 17;
    width: 100%;
  }
}

.button_cutting {
  display: flex;
  justify-content: end;
  align-items: center;
  margin: 5px 10px;
}

.planecolorPicker {
  width: 100%;
  padding: 0px;
}
</style>
